/* test_sha3.c
 *
 * Copyright (C) 2006-2025 wolfSSL Inc.
 *
 * This file is part of wolfSSL.
 *
 * wolfSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * wolfSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
 */

#include <tests/unit.h>

#ifdef NO_INLINE
    #include <wolfssl/wolfcrypt/misc.h>
#else
    #define WOLFSSL_MISC_INCLUDED
    #include <wolfcrypt/src/misc.c>
#endif

#include <wolfssl/wolfcrypt/sha3.h>
#include <wolfssl/wolfcrypt/types.h>
#include <tests/api/api.h>
#include <tests/api/test_sha3.h>
#include <tests/api/test_digest.h>

#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 3)))
    #define WC_SHA3_128_BLOCK_SIZE  168
    #define WC_SHA3_224_BLOCK_SIZE  144
    #define WC_SHA3_256_BLOCK_SIZE  136
    #define WC_SHA3_384_BLOCK_SIZE  104
    #define WC_SHA3_512_BLOCK_SIZE  72
#endif

/*******************************************************************************
 * SHA-3
 ******************************************************************************/

#define SHA3_KATS_TEST(name, upper)                                            \
    (void)i;                                                                   \
                                                                               \
    /* Initialize */                                                           \
    ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0);            \
                                                                               \
    for (i = 0; i < upper##_KAT_CNT; i++) {                                    \
        /* Do KAT. */                                                          \
        ExpectIntEQ(wc_##name##_Update(&dgst, (byte*)dgst_kat[i].input,        \
            (word32)dgst_kat[i].inLen), 0);                                    \
        ExpectIntEQ(wc_##name##_Final(&dgst, hash), 0);                        \
        ExpectBufEQ(hash, (byte*)dgst_kat[i].output,                           \
            WC_##upper##_DIGEST_SIZE);                                         \
    }                                                                          \
                                                                               \
    wc_##name##_Free(&dgst)

#define SHA3_GET_HASH_TEST(name, upper, emptyHashStr, abcHashStr)              \
do {                                                                           \
    wc_Sha3 dgst;                                                              \
    byte hash[WC_##upper##_DIGEST_SIZE];                                       \
    const char* emptyHash = emptyHashStr;                                      \
    const char* abcHash = abcHashStr;                                          \
                                                                               \
    XMEMSET(&dgst, 0, sizeof(dgst));                                           \
                                                                               \
    ExpectIntEQ(wc_Init##name(&dgst, HEAP_HINT, INVALID_DEVID), 0);            \
                                                                               \
    ExpectIntEQ(wc_##name##_GetHash(NULL, NULL),                               \
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));                                        \
    ExpectIntEQ(wc_##name##_GetHash(&dgst, NULL),                              \
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));                                        \
    ExpectIntEQ(wc_##name##_GetHash(NULL, hash),                               \
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));                                        \
                                                                               \
    ExpectIntEQ(wc_##name##_GetHash(&dgst, hash), 0);                          \
    ExpectBufEQ(hash, emptyHash, WC_##upper##_DIGEST_SIZE);                    \
    /* Test that the hash state hasn't been modified. */                       \
    ExpectIntEQ(wc_##name##_Update(&dgst, (byte*)"abc", 3), 0);                \
    ExpectIntEQ(wc_##name##_GetHash(&dgst, hash), 0);                          \
    ExpectBufEQ(hash, abcHash, WC_##upper##_DIGEST_SIZE);                      \
                                                                               \
    wc_##name##_Free(&dgst);                                                   \
} while (0)


int test_wc_InitSha3(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
    DIGEST_INIT_TEST(wc_Sha3, Sha3_224);
    #endif
    #ifndef WOLFSSL_NOSHA3_256
    DIGEST_INIT_TEST(wc_Sha3, Sha3_256);
    #endif
    #ifndef WOLFSSL_NOSHA3_384
    DIGEST_INIT_TEST(wc_Sha3, Sha3_384);
    #endif
    #ifndef WOLFSSL_NOSHA3_512
    DIGEST_INIT_TEST(wc_Sha3, Sha3_512);
    #endif
#endif
    return EXPECT_RESULT();
}

int test_wc_Sha3_Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
    DIGEST_ALT_UPDATE_TEST(wc_Sha3, Sha3_224);
    #endif
    #ifndef WOLFSSL_NOSHA3_256
    DIGEST_ALT_UPDATE_TEST(wc_Sha3, Sha3_256);
    #endif
    #ifndef WOLFSSL_NOSHA3_384
    DIGEST_ALT_UPDATE_TEST(wc_Sha3, Sha3_384);
    #endif
    #ifndef WOLFSSL_NOSHA3_512
    DIGEST_ALT_UPDATE_TEST(wc_Sha3, Sha3_512);
    #endif
#endif
    return EXPECT_RESULT();
}

int test_wc_Sha3_Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA3
    #ifndef WOLFSSL_NOSHA3_224
    DIGEST_ALT_FINAL_TEST(wc_Sha3, Sha3_224, SHA3_224);
    #endif
    #ifndef WOLFSSL_NOSHA3_256
    DIGEST_ALT_FINAL_TEST(wc_Sha3, Sha3_256, SHA3_256);
    #endif
    #ifndef WOLFSSL_NOSHA3_384
    DIGEST_ALT_FINAL_TEST(wc_Sha3, Sha3_384, SHA3_384);
    #endif
    #ifndef WOLFSSL_NOSHA3_512
    DIGEST_ALT_FINAL_TEST(wc_Sha3, Sha3_512, SHA3_512);
    #endif
#endif
    return EXPECT_RESULT();
}

#define SHA3_224_KAT_CNT    7
int test_wc_Sha3_224_KATs(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
    DIGEST_KATS_TEST_VARS(wc_Sha3, SHA3_224);

    DIGEST_KATS_ADD("", 0,
        "\x6b\x4e\x03\x42\x36\x67\xdb\xb7"
        "\x3b\x6e\x15\x45\x4f\x0e\xb1\xab"
        "\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f"
        "\x5b\x5a\x6b\xc7");
    DIGEST_KATS_ADD("a", 1,
        "\x9e\x86\xff\x69\x55\x7c\xa9\x5f"
        "\x40\x5f\x08\x12\x69\x68\x5b\x38"
        "\xe3\xa8\x19\xb3\x09\xee\x94\x2f"
        "\x48\x2b\x6a\x8b");
    DIGEST_KATS_ADD("abc", 3,
        "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a"
        "\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
        "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad"
        "\x73\xb4\x6f\xdf");
    DIGEST_KATS_ADD("message digest", 14,
        "\x18\x76\x8b\xb4\xc4\x8e\xb7\xfc"
        "\x88\xe5\xdd\xb1\x7e\xfc\xf2\x96"
        "\x4a\xbd\x77\x98\xa3\x9d\x86\xa4"
        "\xb4\xa1\xe4\xc8");
    DIGEST_KATS_ADD("abcdefghijklmnopqrstuvwxyz", 26,
        "\x5c\xde\xca\x81\xe1\x23\xf8\x7c"
        "\xad\x96\xb9\xcb\xa9\x99\xf1\x6f"
        "\x6d\x41\x54\x96\x08\xd4\xe0\xf4"
        "\x68\x1b\x82\x39");
    DIGEST_KATS_ADD("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                    "0123456789", 62,
        "\xa6\x7c\x28\x9b\x82\x50\xa6\xf4"
        "\x37\xa2\x01\x37\x98\x5d\x60\x55"
        "\x89\xa8\xc1\x63\xd4\x52\x61\xb1"
        "\x54\x19\x55\x6e");
    DIGEST_KATS_ADD("1234567890123456789012345678901234567890"
                    "1234567890123456789012345678901234567890", 80,
        "\x05\x26\x89\x8e\x18\x58\x69\xf9"
        "\x1b\x3e\x2a\x76\xdd\x72\xa1\x5d"
        "\xc6\x94\x0a\x67\xc8\x16\x4a\x04"
        "\x4c\xd2\x5c\xc8");

    SHA3_KATS_TEST(Sha3_224, SHA3_224);
#endif
    return EXPECT_RESULT();
}

#define SHA3_256_KAT_CNT    7
int test_wc_Sha3_256_KATs(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
    DIGEST_KATS_TEST_VARS(wc_Sha3, SHA3_256);

    DIGEST_KATS_ADD("", 0,
        "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66"
        "\x51\xc1\x47\x56\xa0\x61\xd6\x62"
        "\xf5\x80\xff\x4d\xe4\x3b\x49\xfa"
        "\x82\xd8\x0a\x4b\x80\xf8\x43\x4a");
    DIGEST_KATS_ADD("a", 1,
        "\x80\x08\x4b\xf2\xfb\xa0\x24\x75"
        "\x72\x6f\xeb\x2c\xab\x2d\x82\x15"
        "\xea\xb1\x4b\xc6\xbd\xd8\xbf\xb2"
        "\xc8\x15\x12\x57\x03\x2e\xcd\x8b");
    DIGEST_KATS_ADD("abc", 3,
        "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2"
        "\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
        "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b"
        "\x46\xbf\xe2\x45\x11\x43\x15\x32");
    DIGEST_KATS_ADD("message digest", 14,
        "\xed\xcd\xb2\x06\x93\x66\xe7\x52"
        "\x43\x86\x0c\x18\xc3\xa1\x14\x65"
        "\xec\xa3\x4b\xce\x61\x43\xd3\x0c"
        "\x86\x65\xce\xfc\xfd\x32\xbf\xfd");
    DIGEST_KATS_ADD("abcdefghijklmnopqrstuvwxyz", 26,
        "\x7c\xab\x2d\xc7\x65\xe2\x1b\x24"
        "\x1d\xbc\x1c\x25\x5c\xe6\x20\xb2"
        "\x9f\x52\x7c\x6d\x5e\x7f\x5f\x84"
        "\x3e\x56\x28\x8f\x0d\x70\x75\x21");
    DIGEST_KATS_ADD("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                    "0123456789", 62,
        "\xa7\x9d\x6a\x9d\xa4\x7f\x04\xa3"
        "\xb9\xa9\x32\x3e\xc9\x99\x1f\x21"
        "\x05\xd4\xc7\x8a\x7b\xc7\xbe\xeb"
        "\x10\x38\x55\xa7\xa1\x1d\xfb\x9f");
    DIGEST_KATS_ADD("1234567890123456789012345678901234567890"
                    "1234567890123456789012345678901234567890", 80,
        "\x29\x3e\x5c\xe4\xce\x54\xee\x71"
        "\x99\x0a\xb0\x6e\x51\x1b\x7c\xcd"
        "\x62\x72\x2b\x1b\xeb\x41\x4f\x5f"
        "\xf6\x5c\x82\x74\xe0\xf5\xbe\x1d");

    SHA3_KATS_TEST(Sha3_256, SHA3_256);
#endif
    return EXPECT_RESULT();
}

#define SHA3_384_KAT_CNT    7
int test_wc_Sha3_384_KATs(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
    DIGEST_KATS_TEST_VARS(wc_Sha3, SHA3_384);

    DIGEST_KATS_ADD("", 0,
        "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d"
        "\x01\x10\x7d\x85\x2e\x4c\x24\x85"
        "\xc5\x1a\x50\xaa\xaa\x94\xfc\x61"
        "\x99\x5e\x71\xbb\xee\x98\x3a\x2a"
        "\xc3\x71\x38\x31\x26\x4a\xdb\x47"
        "\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04");
    DIGEST_KATS_ADD("a", 1,
        "\x18\x15\xf7\x74\xf3\x20\x49\x1b"
        "\x48\x56\x9e\xfe\xc7\x94\xd2\x49"
        "\xee\xb5\x9a\xae\x46\xd2\x2b\xf7"
        "\x7d\xaf\xe2\x5c\x5e\xdc\x28\xd7"
        "\xea\x44\xf9\x3e\xe1\x23\x4a\xa8"
        "\x8f\x61\xc9\x19\x12\xa4\xcc\xd9");
    DIGEST_KATS_ADD("abc", 3,
        "\xec\x01\x49\x82\x88\x51\x6f\xc9"
        "\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
        "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25"
        "\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
        "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5"
        "\x39\xf1\xed\xf2\x28\x37\x6d\x25");
    DIGEST_KATS_ADD("message digest", 14,
        "\xd9\x51\x97\x09\xf4\x4a\xf7\x3e"
        "\x2c\x8e\x29\x11\x09\xa9\x79\xde"
        "\x3d\x61\xdc\x02\xbf\x69\xde\xf7"
        "\xfb\xff\xdf\xff\xe6\x62\x75\x15"
        "\x13\xf1\x9a\xd5\x7e\x17\xd4\xb9"
        "\x3b\xa1\xe4\x84\xfc\x19\x80\xd5");
    DIGEST_KATS_ADD("abcdefghijklmnopqrstuvwxyz", 26,
        "\xfe\xd3\x99\xd2\x21\x7a\xaf\x4c"
        "\x71\x7a\xd0\xc5\x10\x2c\x15\x58"
        "\x9e\x1c\x99\x0c\xc2\xb9\xa5\x02"
        "\x90\x56\xa7\xf7\x48\x58\x88\xd6"
        "\xab\x65\xdb\x23\x70\x07\x7a\x5c"
        "\xad\xb5\x3f\xc9\x28\x0d\x27\x8f");
    DIGEST_KATS_ADD("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                    "0123456789", 62,
        "\xd5\xb9\x72\x30\x2f\x50\x80\xd0"
        "\x83\x0e\x0d\xe7\xb6\xb2\xcf\x38"
        "\x36\x65\xa0\x08\xf4\xc4\xf3\x86"
        "\xa6\x11\x12\x65\x2c\x74\x2d\x20"
        "\xcb\x45\xaa\x51\xbd\x4f\x54\x2f"
        "\xc7\x33\xe2\x71\x9e\x99\x92\x91");
    DIGEST_KATS_ADD("1234567890123456789012345678901234567890"
                    "1234567890123456789012345678901234567890", 80,
        "\x3c\x21\x3a\x17\xf5\x14\x63\x8a"
        "\xcb\x3b\xf1\x7f\x10\x9f\x3e\x24"
        "\xc1\x6f\x9f\x14\xf0\x85\xb5\x2a"
        "\x2f\x2b\x81\xad\xc0\xdb\x83\xdf"
        "\x1a\x58\xdb\x2c\xe0\x13\x19\x1b"
        "\x8b\xa7\x2d\x8f\xae\x7e\x2a\x5e");

    SHA3_KATS_TEST(Sha3_384, SHA3_384);
#endif
    return EXPECT_RESULT();
}

#define SHA3_512_KAT_CNT    7
int test_wc_Sha3_512_KATs(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
    DIGEST_KATS_TEST_VARS(wc_Sha3, SHA3_512);

    DIGEST_KATS_ADD("", 0,
        "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5"
        "\xc8\xb5\x67\xdc\x18\x5a\x75\x6e"
        "\x97\xc9\x82\x16\x4f\xe2\x58\x59"
        "\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6"
        "\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c"
        "\x11\xe3\xe9\x40\x2c\x3a\xc5\x58"
        "\xf5\x00\x19\x9d\x95\xb6\xd3\xe3"
        "\x01\x75\x85\x86\x28\x1d\xcd\x26");
    DIGEST_KATS_ADD("a", 1,
        "\x69\x7f\x2d\x85\x61\x72\xcb\x83"
        "\x09\xd6\xb8\xb9\x7d\xac\x4d\xe3"
        "\x44\xb5\x49\xd4\xde\xe6\x1e\xdf"
        "\xb4\x96\x2d\x86\x98\xb7\xfa\x80"
        "\x3f\x4f\x93\xff\x24\x39\x35\x86"
        "\xe2\x8b\x5b\x95\x7a\xc3\xd1\xd3"
        "\x69\x42\x0c\xe5\x33\x32\x71\x2f"
        "\x99\x7b\xd3\x36\xd0\x9a\xb0\x2a");
    DIGEST_KATS_ADD("abc", 3,
        "\xb7\x51\x85\x0b\x1a\x57\x16\x8a"
        "\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
        "\x08\xf6\x21\x82\x74\x44\xf7\x0d"
        "\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
        "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9"
        "\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
        "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5"
        "\x65\x92\xf8\x27\x4e\xec\x53\xf0");
    DIGEST_KATS_ADD("message digest", 14,
        "\x34\x44\xe1\x55\x88\x1f\xa1\x55"
        "\x11\xf5\x77\x26\xc7\xd7\xcf\xe8"
        "\x03\x02\xa7\x43\x30\x67\xb2\x9d"
        "\x59\xa7\x14\x15\xca\x9d\xd1\x41"
        "\xac\x89\x2d\x31\x0b\xc4\xd7\x81"
        "\x28\xc9\x8f\xda\x83\x9d\x18\xd7"
        "\xf0\x55\x6f\x2f\xe7\xac\xb3\xc0"
        "\xcd\xa4\xbf\xf3\xa2\x5f\x5f\x59");
    DIGEST_KATS_ADD("abcdefghijklmnopqrstuvwxyz", 26,
        "\xaf\x32\x8d\x17\xfa\x28\x75\x3a"
        "\x3c\x9f\x5c\xb7\x2e\x37\x6b\x90"
        "\x44\x0b\x96\xf0\x28\x9e\x57\x03"
        "\xb7\x29\x32\x4a\x97\x5a\xb3\x84"
        "\xed\xa5\x65\xfc\x92\xaa\xde\xd1"
        "\x43\x66\x99\x00\xd7\x61\x86\x16"
        "\x87\xac\xdc\x0a\x5f\xfa\x35\x8b"
        "\xd0\x57\x1a\xaa\xd8\x0a\xca\x68");
    DIGEST_KATS_ADD("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                    "0123456789", 62,
        "\xd1\xdb\x17\xb4\x74\x5b\x25\x5e"
        "\x5e\xb1\x59\xf6\x65\x93\xcc\x9c"
        "\x14\x38\x50\x97\x9f\xc7\xa3\x95"
        "\x17\x96\xab\xa8\x01\x65\xaa\xb5"
        "\x36\xb4\x61\x74\xce\x19\xe3\xf7"
        "\x07\xf0\xe5\xc6\x48\x7f\x5f\x03"
        "\x08\x4b\xc0\xec\x94\x61\x69\x1e"
        "\xf2\x01\x13\xe4\x2a\xd2\x81\x63");
    DIGEST_KATS_ADD("1234567890123456789012345678901234567890"
                    "1234567890123456789012345678901234567890", 80,
        "\x95\x24\xb9\xa5\x53\x6b\x91\x06"
        "\x95\x26\xb4\xf6\x19\x6b\x7e\x94"
        "\x75\xb4\xda\x69\xe0\x1f\x0c\x85"
        "\x57\x97\xf2\x24\xcd\x73\x35\xdd"
        "\xb2\x86\xfd\x99\xb9\xb3\x2f\xfe"
        "\x33\xb5\x9a\xd4\x24\xcc\x17\x44"
        "\xf6\xeb\x59\x13\x7f\x5f\xb8\x60"
        "\x19\x32\xe8\xa8\xaf\x0a\xe9\x30");

    SHA3_KATS_TEST(Sha3_512, SHA3_512);
#endif
    return EXPECT_RESULT();
}

int test_wc_Sha3_other(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
    DIGEST_ALT_OTHER_TEST(wc_Sha3, Sha3_224, SHA3_224,
        "\xbb\x4e\xb3\xf7\xfb\x7b\x50\xff"
        "\x3b\xf8\xb0\x53\x8c\x13\x40\xce"
        "\x0c\x43\x5f\xff\x6a\x08\x43\x87"
        "\x34\x9f\x7a\x4c");
#endif
#ifndef WOLFSSL_NOSHA3_256
    DIGEST_ALT_OTHER_TEST(wc_Sha3, Sha3_256, SHA3_256,
        "\x78\xc4\x14\xa4\x5d\x85\x07\xf4"
        "\x48\x64\xe0\x5f\x73\x2c\x3b\x78"
        "\xce\x5a\x78\x45\x97\x0b\x29\xa8"
        "\xb4\x53\xed\x38\x19\xd2\x4e\xa9");
#endif
#ifndef WOLFSSL_NOSHA3_384
    DIGEST_ALT_OTHER_TEST(wc_Sha3, Sha3_384, SHA3_384,
        "\x22\x29\x8c\x46\xa7\xf0\xf9\xc7"
        "\xa7\xaf\x66\x5d\x58\x88\xb3\x6c"
        "\xc2\x02\x43\x83\x71\x5f\xce\x12"
        "\x65\x1b\x11\xba\x1c\xde\x52\xdc"
        "\x6f\xde\x26\x43\xf1\x9f\xbe\xea"
        "\x5f\xd6\x25\x06\x7c\xad\x16\xed");
#endif
#ifndef WOLFSSL_NOSHA3_512
    DIGEST_ALT_OTHER_TEST(wc_Sha3, Sha3_512, SHA3_512,
        "\xc3\xaf\x62\x06\x69\x92\xa1\x2f"
        "\xa5\x66\xcc\xcd\xec\x80\xdd\x27"
        "\x93\xbd\x11\xb0\xb7\xba\x6a\x5e"
        "\x36\xcf\x23\x4c\x1a\xf4\x8d\x37"
        "\xb9\xb6\x7f\xb1\xb4\x9a\x04\x23"
        "\x23\x42\x51\x5d\x8f\x07\x0d\x42"
        "\x04\x68\x84\xc4\x56\x24\x14\x65"
        "\x84\x28\xa9\x2f\x10\x35\x7b\x6d");
#endif
#endif
    return EXPECT_RESULT();
}

int test_wc_Sha3_Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
    DIGEST_ALT_COPY_TEST(wc_Sha3, Sha3_224, SHA3_224,
        "\x6b\x4e\x03\x42\x36\x67\xdb\xb7"
        "\x3b\x6e\x15\x45\x4f\x0e\xb1\xab"
        "\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f"
        "\x5b\x5a\x6b\xc7",
        "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a"
        "\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
        "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad"
        "\x73\xb4\x6f\xdf");
#endif
#ifndef WOLFSSL_NOSHA3_256
    DIGEST_ALT_COPY_TEST(wc_Sha3, Sha3_256, SHA3_256,
        "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66"
        "\x51\xc1\x47\x56\xa0\x61\xd6\x62"
        "\xf5\x80\xff\x4d\xe4\x3b\x49\xfa"
        "\x82\xd8\x0a\x4b\x80\xf8\x43\x4a",
        "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2"
        "\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
        "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b"
        "\x46\xbf\xe2\x45\x11\x43\x15\x32");
#endif
#ifndef WOLFSSL_NOSHA3_384
    DIGEST_ALT_COPY_TEST(wc_Sha3, Sha3_384, SHA3_384,
        "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d"
        "\x01\x10\x7d\x85\x2e\x4c\x24\x85"
        "\xc5\x1a\x50\xaa\xaa\x94\xfc\x61"
        "\x99\x5e\x71\xbb\xee\x98\x3a\x2a"
        "\xc3\x71\x38\x31\x26\x4a\xdb\x47"
        "\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04",
        "\xec\x01\x49\x82\x88\x51\x6f\xc9"
        "\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
        "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25"
        "\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
        "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5"
        "\x39\xf1\xed\xf2\x28\x37\x6d\x25");
#endif
#ifndef WOLFSSL_NOSHA3_512
    DIGEST_ALT_COPY_TEST(wc_Sha3, Sha3_512, SHA3_512,
        "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5"
        "\xc8\xb5\x67\xdc\x18\x5a\x75\x6e"
        "\x97\xc9\x82\x16\x4f\xe2\x58\x59"
        "\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6"
        "\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c"
        "\x11\xe3\xe9\x40\x2c\x3a\xc5\x58"
        "\xf5\x00\x19\x9d\x95\xb6\xd3\xe3"
        "\x01\x75\x85\x86\x28\x1d\xcd\x26",
        "\xb7\x51\x85\x0b\x1a\x57\x16\x8a"
        "\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
        "\x08\xf6\x21\x82\x74\x44\xf7\x0d"
        "\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
        "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9"
        "\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
        "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5"
        "\x65\x92\xf8\x27\x4e\xec\x53\xf0");
#endif
#endif
    return EXPECT_RESULT();
}

int test_wc_Sha3_GetHash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHA3
#ifndef WOLFSSL_NOSHA3_224
    SHA3_GET_HASH_TEST(Sha3_224, SHA3_224,
        "\x6b\x4e\x03\x42\x36\x67\xdb\xb7"
        "\x3b\x6e\x15\x45\x4f\x0e\xb1\xab"
        "\xd4\x59\x7f\x9a\x1b\x07\x8e\x3f"
        "\x5b\x5a\x6b\xc7",
        "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a"
        "\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
        "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad"
        "\x73\xb4\x6f\xdf");
#endif
#ifndef WOLFSSL_NOSHA3_256
    SHA3_GET_HASH_TEST(Sha3_256, SHA3_256,
        "\xa7\xff\xc6\xf8\xbf\x1e\xd7\x66"
        "\x51\xc1\x47\x56\xa0\x61\xd6\x62"
        "\xf5\x80\xff\x4d\xe4\x3b\x49\xfa"
        "\x82\xd8\x0a\x4b\x80\xf8\x43\x4a",
        "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2"
        "\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
        "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b"
        "\x46\xbf\xe2\x45\x11\x43\x15\x32");
#endif
#ifndef WOLFSSL_NOSHA3_384
    SHA3_GET_HASH_TEST(Sha3_384, SHA3_384,
        "\x0c\x63\xa7\x5b\x84\x5e\x4f\x7d"
        "\x01\x10\x7d\x85\x2e\x4c\x24\x85"
        "\xc5\x1a\x50\xaa\xaa\x94\xfc\x61"
        "\x99\x5e\x71\xbb\xee\x98\x3a\x2a"
        "\xc3\x71\x38\x31\x26\x4a\xdb\x47"
        "\xfb\x6b\xd1\xe0\x58\xd5\xf0\x04",
        "\xec\x01\x49\x82\x88\x51\x6f\xc9"
        "\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
        "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25"
        "\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
        "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5"
        "\x39\xf1\xed\xf2\x28\x37\x6d\x25");
#endif
#ifndef WOLFSSL_NOSHA3_512
    SHA3_GET_HASH_TEST(Sha3_512, SHA3_512,
        "\xa6\x9f\x73\xcc\xa2\x3a\x9a\xc5"
        "\xc8\xb5\x67\xdc\x18\x5a\x75\x6e"
        "\x97\xc9\x82\x16\x4f\xe2\x58\x59"
        "\xe0\xd1\xdc\xc1\x47\x5c\x80\xa6"
        "\x15\xb2\x12\x3a\xf1\xf5\xf9\x4c"
        "\x11\xe3\xe9\x40\x2c\x3a\xc5\x58"
        "\xf5\x00\x19\x9d\x95\xb6\xd3\xe3"
        "\x01\x75\x85\x86\x28\x1d\xcd\x26",
        "\xb7\x51\x85\x0b\x1a\x57\x16\x8a"
        "\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
        "\x08\xf6\x21\x82\x74\x44\xf7\x0d"
        "\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
        "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9"
        "\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
        "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5"
        "\x65\x92\xf8\x27\x4e\xec\x53\xf0");
#endif
#endif
    return EXPECT_RESULT();
}

int test_wc_Sha3_Flags(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_SHA3) && defined(WOLFSSL_HASH_FLAGS) && \
    !defined(WOLFSSL_NOSHA3_256)
    DIGEST_ALT_FLAGS_TEST(wc_Sha3, Sha3, Sha3_256);
#endif
    return EXPECT_RESULT();
}

/*******************************************************************************
 * SHAKE-128
 ******************************************************************************/

int test_wc_InitShake128(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    DIGEST_INIT_TEST(wc_Shake, Shake128);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128_Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    DIGEST_ALT_UPDATE_TEST(wc_Shake, Shake128);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128_Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    DIGEST_COUNT_FINAL_TEST(wc_Shake, Shake128, SHA3_128);
#endif
    return EXPECT_RESULT();
}

#define SHAKE128_KAT_CNT    7
int test_wc_Shake128_KATs(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    DIGEST_COUNT_KATS_TEST_VARS(wc_Shake, SHAKE128, SHA3_128);

    DIGEST_KATS_ADD("", 0,
        "\x7f\x9c\x2b\xa4\xe8\x8f\x82\x7d"
        "\x61\x60\x45\x50\x76\x05\x85\x3e"
        "\xd7\x3b\x80\x93\xf6\xef\xbc\x88"
        "\xeb\x1a\x6e\xac\xfa\x66\xef\x26"
        "\x3c\xb1\xee\xa9\x88\x00\x4b\x93"
        "\x10\x3c\xfb\x0a\xee\xfd\x2a\x68"
        "\x6e\x01\xfa\x4a\x58\xe8\xa3\x63"
        "\x9c\xa8\xa1\xe3\xf9\xae\x57\xe2"
        "\x35\xb8\xcc\x87\x3c\x23\xdc\x62"
        "\xb8\xd2\x60\x16\x9a\xfa\x2f\x75"
        "\xab\x91\x6a\x58\xd9\x74\x91\x88"
        "\x35\xd2\x5e\x6a\x43\x50\x85\xb2"
        "\xba\xdf\xd6\xdf\xaa\xc3\x59\xa5"
        "\xef\xbb\x7b\xcc\x4b\x59\xd5\x38"
        "\xdf\x9a\x04\x30\x2e\x10\xc8\xbc"
        "\x1c\xbf\x1a\x0b\x3a\x51\x20\xea"
        "\x17\xcd\xa7\xcf\xad\x76\x5f\x56"
        "\x23\x47\x4d\x36\x8c\xcc\xa8\xaf"
        "\x00\x07\xcd\x9f\x5e\x4c\x84\x9f"
        "\x16\x7a\x58\x0b\x14\xaa\xbd\xef"
        "\xae\xe7\xee\xf4\x7c\xb0\xfc\xa9");
    DIGEST_KATS_ADD("a", 1,
        "\x85\xc8\xde\x88\xd2\x88\x66\xbf"
        "\x08\x68\x09\x0b\x39\x61\x16\x2b"
        "\xf8\x23\x92\xf6\x90\xd9\xe4\x73"
        "\x09\x10\xf4\xaf\x7c\x6a\xb3\xee"
        "\x43\x54\xb4\x9c\xa7\x29\xeb\x35"
        "\x6e\xe3\xf5\xb0\xfb\xd2\x9b\x66"
        "\x76\x93\x83\xe5\xe4\x01\xb1\xf8"
        "\x5e\x04\x4c\x92\xbb\x52\x31\xaa"
        "\x4d\xee\x17\x99\xaf\x7a\x7c\xee"
        "\x21\x3a\x23\xad\xcd\x03\xc4\x80"
        "\x6c\x9a\x8b\x0d\x8a\x2e\xea\xd8"
        "\xea\x7a\x61\x34\xc1\x3e\x52\x3c"
        "\xcf\x93\xad\x39\xd2\x27\xd3\xe7"
        "\xd0\x22\xd9\x65\x4f\x3b\x49\x41"
        "\x37\x88\x75\x8a\x64\x17\xe4\x2d"
        "\x41\x95\x7c\xb3\x0c\xf0\x4d\xa3"
        "\x7f\x26\x89\x7c\x2c\xf2\xf8\x00"
        "\x55\x84\x62\x93\xfd\xe0\x23\x31"
        "\xcf\x4a\x26\x9a\xaf\x2d\x47\xeb"
        "\x27\xab\xa0\xfa\xba\x4a\x67\x8e"
        "\xc0\x02\xbc\x0d\x30\x64\xea\xd0");
    DIGEST_KATS_ADD("abc", 3,
        "\x58\x81\x09\x2d\xd8\x18\xbf\x5c"
        "\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
        "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f"
        "\x97\xb8\x33\x51\x94\x0f\x2c\xc8"
        "\x44\xc5\x0a\xf3\x2a\xcd\x3f\x2c"
        "\xdd\x06\x65\x68\x70\x6f\x50\x9b"
        "\xc1\xbd\xde\x58\x29\x5d\xae\x3f"
        "\x89\x1a\x9a\x0f\xca\x57\x83\x78"
        "\x9a\x41\xf8\x61\x12\x14\xce\x61"
        "\x23\x94\xdf\x28\x6a\x62\xd1\xa2"
        "\x25\x2a\xa9\x4d\xb9\xc5\x38\x95"
        "\x6c\x71\x7d\xc2\xbe\xd4\xf2\x32"
        "\xa0\x29\x4c\x85\x7c\x73\x0a\xa1"
        "\x60\x67\xac\x10\x62\xf1\x20\x1f"
        "\xb0\xd3\x77\xcf\xb9\xcd\xe4\xc6"
        "\x35\x99\xb2\x7f\x34\x62\xbb\xa4"
        "\xa0\xed\x29\x6c\x80\x1f\x9f\xf7"
        "\xf5\x73\x02\xbb\x30\x76\xee\x14"
        "\x5f\x97\xa3\x2a\xe6\x8e\x76\xab"
        "\x66\xc4\x8d\x51\x67\x5b\xd4\x9a"
        "\xcc\x29\x08\x2f\x56\x47\x58\x4e");
    DIGEST_KATS_ADD("message digest", 14,
        "\xcb\xef\x73\x29\x61\xb5\x5b\x4c"
        "\x31\x39\x67\x96\x57\x7d\xf4\x91"
        "\xb6\xee\xd6\x1d\x89\x49\xce\x96"
        "\x72\x26\x80\x1e\x41\x1e\x53\xf0"
        "\x95\x44\xc1\x3f\xe4\xdf\x40\xfc"
        "\x8d\xf5\xf9\x85\x3e\x85\x41\xd0"
        "\x45\x41\xf1\x00\x77\xd9\xd4\x4e"
        "\x74\x93\xe8\x7f\x16\x0a\x0a\x0d"
        "\x37\xb3\xd6\xda\xc9\x64\x59\x88"
        "\xed\x5d\x06\xdd\x53\x21\x99\x3d"
        "\x87\x35\x74\xd1\x47\xe3\x36\xd7"
        "\x23\x3a\x68\x27\x31\x87\x21\x48"
        "\xe9\x3e\x72\x28\x16\xb3\xb1\xcc"
        "\x31\x3b\xc4\x33\x94\x5f\x74\xf2"
        "\x14\x39\xdf\xd8\xc8\x9b\xc5\x9b"
        "\xf3\xd1\x6d\x48\x9a\x5d\x5c\xaf"
        "\xdf\x77\xac\x07\xbe\x5d\x96\xa7"
        "\x6e\x95\x27\x53\x07\xd8\x83\xca"
        "\xd6\x25\x71\x43\xb5\x61\x00\x73"
        "\xcb\xbf\x7b\x8e\x89\x70\x31\x74"
        "\x66\xa8\xb6\x85\xd4\x81\x78\xb8");
    DIGEST_KATS_ADD("abcdefghijklmnopqrstuvwxyz", 26,
        "\x96\x1c\x91\x9c\x08\x54\x57\x6e"
        "\x56\x13\x20\xe8\x15\x14\xbf\x37"
        "\x24\x19\x7d\x07\x15\xe1\x6a\x36"
        "\x45\x20\x38\x4e\xe9\x97\xf6\xef"
        "\x3b\xe7\xad\x1a\xb6\x87\xd3\x1e"
        "\xbd\x7e\x66\x04\xef\x2c\x76\x52"
        "\x93\x2e\x42\x06\x11\x3d\x26\x35"
        "\x14\xe7\x2f\x31\xf5\xe1\xdf\x87"
        "\xc5\xf5\x4f\xc4\x3e\x8f\x85\x7f"
        "\xc4\xa5\x2b\xbb\x56\x5b\xd6\xd4"
        "\x58\x69\xdf\x92\x59\xc0\x97\x74"
        "\x72\x83\x94\xe3\xe0\xc3\xb3\x26"
        "\x41\x00\x85\xc3\x56\xe5\xb1\x73"
        "\xd5\x70\x08\x79\x45\xb0\xf0\x68"
        "\xe4\xc6\x3a\x5b\x19\x1f\xef\x22"
        "\xd9\x3b\x9f\xd4\x21\x13\x28\xd7"
        "\x0e\x51\x4f\xec\x92\xb1\xb4\x86"
        "\x43\x49\x59\x18\xb6\x41\xea\xb0"
        "\x54\x60\xd0\x79\x8c\xbe\x42\xfd"
        "\xa4\x7a\x23\x75\xf1\x06\x5d\x03"
        "\x7e\xbc\x76\xbd\xce\xff\x29\xef");
    DIGEST_KATS_ADD("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                    "0123456789", 62,
        "\x54\xdd\x20\x1e\x53\x24\x99\x10"
        "\xdb\x3c\x7d\x36\x65\x74\xfb\xb6"
        "\x4e\x71\xfa\xe4\x42\xa4\xba\xc1"
        "\x34\x39\xf2\x6d\xd4\x89\x68\x83"
        "\x70\xd0\x12\xa1\x55\x86\xd8\x7e"
        "\x73\x00\xbe\xed\xd9\x23\x3e\xea"
        "\x98\xf9\x16\xda\xb2\x66\x51\x38"
        "\x02\x50\x24\x40\x31\x5b\xba\x9e"
        "\x40\xcd\xb8\x60\x09\x7b\x12\xdf"
        "\xd8\x8d\x4f\x24\x2f\x77\xc2\x2e"
        "\x93\xad\xfd\x3e\xb7\x89\x94\x82"
        "\xd3\x9f\x7c\x0f\x16\x0e\xcc\x07"
        "\x04\x73\x47\x82\x94\x73\x31\x46"
        "\x74\xa5\x6a\x13\xe7\x01\xd5\xd8"
        "\xaa\x37\x54\x6b\x43\xc5\x73\x36"
        "\x56\xc1\xac\x3c\xa4\x69\x7a\x30"
        "\x32\x0b\x98\xad\xf9\xbc\xa3\xc6"
        "\x8b\xec\x9f\x14\xe3\x3b\x8f\xae"
        "\x30\xd5\x5e\xc6\x0e\x80\x15\xa5"
        "\x16\x80\xbb\x37\xeb\x5a\x7e\xbc"
        "\x90\x88\xcd\xcf\x09\xff\x2d\x6b");
    DIGEST_KATS_ADD("1234567890123456789012345678901234567890"
                    "1234567890123456789012345678901234567890", 80,
        "\x7b\xf4\x51\xc9\x2f\xdc\x77\xb9"
        "\x77\x1e\x6c\x90\x56\x44\x58\x94"
        "\xee\x86\x7f\x00\xc2\xb7\x0d\x3a"
        "\xf0\xd1\x96\xa0\xcf\x6b\x28\xe1"
        "\x2c\xed\x96\x05\x37\xf2\x2a\x0e"
        "\x90\x33\x41\x03\x67\x58\x44\x99"
        "\x3c\x4f\xd7\x13\x64\x68\x00\xbd"
        "\x89\x99\x51\xe5\x6f\x06\x45\xfc"
        "\xf0\x39\x78\xa6\x27\xc0\x7c\x62"
        "\xa7\x5a\x54\x3b\x8a\xf7\xed\xb0"
        "\xaf\xe7\x64\x3d\x94\x95\x36\x3b"
        "\x30\xbc\xc5\x50\x1c\x74\xdf\x19"
        "\x5b\x2a\xd4\x28\x83\x1b\x77\x9b"
        "\xf1\xab\x2a\x0d\xfc\x92\xa5\x92"
        "\x5a\xc8\xd5\x97\x90\xee\xbc\xf2"
        "\xec\x29\xb3\x33\x8f\x66\x0c\x5a"
        "\x6f\x66\x73\xce\x32\x2c\xc1\x03"
        "\x9a\xe5\xf1\x46\x3b\x86\xca\x7e"
        "\x96\xaa\xa9\x9a\x27\x09\x93\x02"
        "\x6a\xc8\x13\xda\xc4\xb9\xeb\x82"
        "\x14\xe3\x1c\xe8\x68\x27\xcb\x21");

    DIGEST_COUNT_KATS_TEST(Shake128, SHAKE128, SHA3_128);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128_other(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    DIGEST_COUNT_OTHER_TEST(wc_Shake, Shake128, SHA3_128,
        "\x1b\xbe\x22\xa0\x40\xc7\x15\x88"
        "\xcc\x2b\xaa\x3e\x5a\x7c\x89\x03"
        "\x33\xd4\xac\x54\x27\x14\xf9\x96"
        "\x0e\x60\x3d\x8f\x13\x9a\xf8\x1e"
        "\x8f\x45\xc8\x37\xa8\x63\x16\x7b"
        "\x96\x69\xd4\xe4\x2e\x45\x9f\x1d"
        "\x50\xaa\x92\x2e\x0d\x32\x37\x97"
        "\xf7\xd7\xcc\x7c\x5c\xfa\x71\x42"
        "\xf3\x23\x68\x6a\x36\x03\xd4\x0a"
        "\x77\x7d\xd3\x84\x40\x75\xc5\xad"
        "\x1f\xb7\xa4\x90\x80\x66\x91\x49"
        "\x7d\x3e\x8a\x69\xb9\x94\xbf\x0f"
        "\x0a\x09\xde\xc8\xfe\x10\xb5\x4f"
        "\xe5\x78\xda\x4c\x3a\xcd\xcd\xc2"
        "\x30\xb0\x14\x75\x45\x2b\x2e\x40"
        "\x74\xf4\x5c\xad\x2e\xcf\x1c\xa0"
        "\x0b\x8d\x58\x30\xcd\x0f\xaa\x11"
        "\x68\x84\x2b\x55\xa7\x62\x1b\x9a"
        "\xec\x6e\xd6\xcc\xa1\xc9\x9f\xc8"
        "\x11\x74\xb4\x22\x18\xc0\xe6\x37"
        "\xc4\xef\xc2\xe4\xc3\x26\x27\x0b");
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128_Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    DIGEST_COUNT_COPY_TEST(wc_Shake, Shake128, SHA3_128,
        "\x7f\x9c\x2b\xa4\xe8\x8f\x82\x7d"
        "\x61\x60\x45\x50\x76\x05\x85\x3e"
        "\xd7\x3b\x80\x93\xf6\xef\xbc\x88"
        "\xeb\x1a\x6e\xac\xfa\x66\xef\x26"
        "\x3c\xb1\xee\xa9\x88\x00\x4b\x93"
        "\x10\x3c\xfb\x0a\xee\xfd\x2a\x68"
        "\x6e\x01\xfa\x4a\x58\xe8\xa3\x63"
        "\x9c\xa8\xa1\xe3\xf9\xae\x57\xe2"
        "\x35\xb8\xcc\x87\x3c\x23\xdc\x62"
        "\xb8\xd2\x60\x16\x9a\xfa\x2f\x75"
        "\xab\x91\x6a\x58\xd9\x74\x91\x88"
        "\x35\xd2\x5e\x6a\x43\x50\x85\xb2"
        "\xba\xdf\xd6\xdf\xaa\xc3\x59\xa5"
        "\xef\xbb\x7b\xcc\x4b\x59\xd5\x38"
        "\xdf\x9a\x04\x30\x2e\x10\xc8\xbc"
        "\x1c\xbf\x1a\x0b\x3a\x51\x20\xea"
        "\x17\xcd\xa7\xcf\xad\x76\x5f\x56"
        "\x23\x47\x4d\x36\x8c\xcc\xa8\xaf"
        "\x00\x07\xcd\x9f\x5e\x4c\x84\x9f"
        "\x16\x7a\x58\x0b\x14\xaa\xbd\xef"
        "\xae\xe7\xee\xf4\x7c\xb0\xfc\xa9",
        "\x58\x81\x09\x2d\xd8\x18\xbf\x5c"
        "\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
        "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f"
        "\x97\xb8\x33\x51\x94\x0f\x2c\xc8"
        "\x44\xc5\x0a\xf3\x2a\xcd\x3f\x2c"
        "\xdd\x06\x65\x68\x70\x6f\x50\x9b"
        "\xc1\xbd\xde\x58\x29\x5d\xae\x3f"
        "\x89\x1a\x9a\x0f\xca\x57\x83\x78"
        "\x9a\x41\xf8\x61\x12\x14\xce\x61"
        "\x23\x94\xdf\x28\x6a\x62\xd1\xa2"
        "\x25\x2a\xa9\x4d\xb9\xc5\x38\x95"
        "\x6c\x71\x7d\xc2\xbe\xd4\xf2\x32"
        "\xa0\x29\x4c\x85\x7c\x73\x0a\xa1"
        "\x60\x67\xac\x10\x62\xf1\x20\x1f"
        "\xb0\xd3\x77\xcf\xb9\xcd\xe4\xc6"
        "\x35\x99\xb2\x7f\x34\x62\xbb\xa4"
        "\xa0\xed\x29\x6c\x80\x1f\x9f\xf7"
        "\xf5\x73\x02\xbb\x30\x76\xee\x14"
        "\x5f\x97\xa3\x2a\xe6\x8e\x76\xab"
        "\x66\xc4\x8d\x51\x67\x5b\xd4\x9a"
        "\xcc\x29\x08\x2f\x56\x47\x58\x4e");
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128Hash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    const byte  data[] = { /* Hello World */
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
        0x72,0x6c,0x64
    };
    word32      len = sizeof(data);
    byte        hash[WC_SHA3_128_COUNT * 8];
    word32      hashLen = sizeof(hash);
    const char* expHash =
        "\x12\x27\xc5\xf8\x82\xf9\xc5\x7b"
        "\xf2\xe3\xe4\x8d\x2c\x87\xeb\x20"
        "\xf3\x82\xa4\xb6\x39\xb5\x4d\x26"
        "\xf6\xd5\x95\xff\x3d\xb9\x06\x4d"
        "\x07\x4e\xe7\x88\xf0\x74\x7c\xa3"
        "\xfc\x46\xce\x86\x93\x6c\xfc\x6b"
        "\xd3\x63\x8d\xae\x5a\x2b\x7d\x65"
        "\x92\x52\x29\x98\xd6\xda\x6f\xaa"
        "\x5f\x5d\x41\x5d\x99\xd5\x56\x51"
        "\x46\xee\x3c\xd2\xb8\xec\x15\x38"
        "\xbc\x62\xdd\xe9\x46\x94\x9b\x23"
        "\xb8\xcf\x3c\xa3\xe4\x7f\x35\x2d"
        "\x3c\x46\x2f\x16\x87\x10\x84\x34"
        "\xf7\x84\x95\x2c\xcf\xe3\x26\xaf"
        "\xdf\x78\x53\xb3\x98\x20\x22\xca"
        "\x14\x82\xbc\x9c\xd1\x8f\x9a\x6c"
        "\xe0\x92\x0b\x8f\x34\x5a\xa0\x4e"
        "\x7f\xd5\x83\xa4\xe2\x01\x25\x33"
        "\x45\x0b\x00\xc1\x6a\x5a\x14\xe8"
        "\x6a\xd1\x45\x0c\x4e\x8a\x4a\x6f"
        "\x37\xb4\x15\x5d\xd6\x0d\xd1\xab";

    ExpectIntEQ(wc_Shake128Hash(data, len, hash, hashLen), 0);
    ExpectBufEQ(hash, expHash, hashLen);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128_Absorb(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    wc_Shake shake128;

    ExpectIntEQ(wc_InitShake128(&shake128, HEAP_HINT, INVALID_DEVID), 0);

#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)
    ExpectIntEQ(wc_Shake128_Absorb(NULL     , NULL    , 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake128_Absorb(&shake128, NULL    , 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake128_Absorb(NULL     , NULL    , 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Shake128_Absorb(&shake128, NULL, 0), 0);
#endif

    ExpectIntEQ(wc_Shake128_Absorb(&shake128, (byte*)"a", 1), 0);

    wc_Shake128_Free(&shake128);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake128_SqueezeBlocks(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    wc_Shake shake128;
    byte hash[WC_SHA3_128_COUNT * 8];

    ExpectIntEQ(wc_InitShake128(&shake128, HEAP_HINT, INVALID_DEVID), 0);

#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)
    ExpectIntEQ(wc_Shake128_SqueezeBlocks(NULL     , NULL, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake128_SqueezeBlocks(&shake128, NULL, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake128_SqueezeBlocks(NULL     , NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Shake128_SqueezeBlocks(&shake128, NULL, 0), 0);
#endif
    ExpectIntEQ(wc_Shake128_SqueezeBlocks(&shake128, hash, 1), 0);

    wc_Shake128_Free(&shake128);
#endif
    return EXPECT_RESULT();
}

#define TEST_SHAKE128_MAX_BLOCKS     3
int test_wc_Shake128_XOF(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE128
    wc_Shake shake128;
    byte hash[WC_SHA3_128_COUNT * 8 * TEST_SHAKE128_MAX_BLOCKS];
    const char* expOut =
        "\xf4\x2f\xac\xcf\x13\x0e\x25\x5f"
        "\xfd\x4a\x29\xbb\x9d\x47\x25\xea"
        "\x19\xfe\x86\xd3\xeb\x58\xd7\x74"
        "\xc1\x3c\xf9\xc7\x0e\xdc\xc6\x3b"
        "\x4b\x97\x0d\x2b\xbc\xa6\x89\x4c"
        "\xda\x48\x8c\x02\x62\x15\x1f\x2e"
        "\x36\xb1\x95\x78\xfe\x02\x81\x35"
        "\x30\x55\x5f\x3c\x06\x47\x2b\x93"
        "\x1e\xf5\x8e\xf2\xfc\x81\x5b\xec"
        "\x9f\xde\xf3\xee\xc0\xac\xb0\x90"
        "\x5c\x19\xc8\x3e\x8a\xa4\xf6\xa7"
        "\xdf\xa3\x39\xdf\x22\x03\x6c\x07"
        "\xaa\xbb\xea\x3d\xec\x00\xc2\xb2"
        "\x6e\x4c\x6b\xdc\xb8\x39\x8b\xb5"
        "\x67\x3f\xdc\x2a\xf5\x91\x32\xb9"
        "\x07\xbc\x1d\xb3\x92\x79\x13\xdb"
        "\x56\xe5\xae\x43\x91\x58\x18\x41"
        "\xa8\xe1\x75\x8e\x5b\xeb\xac\x4f"
        "\xeb\x41\xac\x5d\x8b\x4a\x3d\xf6"
        "\xb6\x5f\xe6\x9c\x19\x1e\x33\x97"
        "\xbc\x7c\xa7\x7e\xed\x5c\xe5\x4b"
        "\xdb\xa2\x34\xcd\x90\x94\x46\x19"
        "\x2e\x60\xbb\xf4\xb1\xe6\x78\xc8"
        "\xb2\x89\x0b\x2b\x0a\xb9\x69\x81"
        "\x90\x36\xc7\x5e\xcc\x36\x46\xde"
        "\x5e\x1d\xb2\x1d\x62\x46\x58\xdf"
        "\x9a\x07\xea\xe5\x6e\xac\x06\x53"
        "\x4f\xb4\xb5\x1e\xe3\x78\x60\x84"
        "\xe0\x96\xfd\xe8\xc0\xf4\x3b\x80"
        "\x7a\x2d\xb5\x22\x3e\xb5\x0f\x21"
        "\xcb\x47\x13\x2d\x97\xb5\x28\x25"
        "\xe7\x84\xa1\x64\x46\xa8\xeb\x8d"
        "\xa7\xf9\xbe\x89\x3f\x96\x8a\x08"
        "\x97\x8d\x5c\x72\x7c\x9d\x52\x27"
        "\xea\xb2\xf0\x9d\x9c\x00\x0d\x3e"
        "\xd1\xa4\x0f\xdd\xba\x43\x41\xfb"
        "\xf8\x26\x13\x98\x27\x88\xae\x8b"
        "\xfb\x8f\xcd\x37\x72\xb3\x37\x09"
        "\xf4\xde\xde\x33\x8e\x1f\xbd\x49"
        "\x90\x3c\x8a\x8b\xd2\x89\xb0\x26"
        "\x39\xc8\x2f\xc7\xfc\x2d\xf9\xa7"
        "\xd3\x5d\x69\x3d\x90\x17\x9c\xc1"
        "\x83\xc7\x1d\xd6\xd3\xa2\x01\x57"
        "\x33\x4f\x0d\xfc\x52\x9e\x2a\xd1"
        "\x9e\xfb\x36\xdf\x3e\xb3\x49\x9f"
        "\x83\x22\xa8\x24\x0e\xa1\xfb\xca"
        "\xd5\x17\x58\x1a\x40\x3f\x4f\x54"
        "\x3f\xd4\xed\x99\xd2\x39\xad\x37"
        "\x03\x39\xf7\x3b\xcf\x52\x55\xc4"
        "\x76\x74\x1d\x33\x04\x76\x44\x0d"
        "\xf6\x93\x89\x9d\x74\x19\x9c\x09"
        "\xd9\xf4\x5f\x0b\xbc\xf4\x13\xec"
        "\x2c\xce\x5f\x2b\x00\xeb\x8b\xa0"
        "\xa2\xf1\xdd\x93\xc0\x9c\x7c\xb5"
        "\xca\xe2\xfb\x07\xa9\x1b\xa8\xc9"
        "\xc9\x84\x2b\x7e\x1e\x05\x8c\x98"
        "\xfd\x8d\x2a\xd0\xf2\x3a\x7b\x88"
        "\x26\x4d\xed\x2b\xdb\x99\xb8\x9f"
        "\x88\x01\x47\x29\xeb\x23\x80\x81"
        "\x2b\xdd\xac\xbf\xcb\x1e\x80\x0d"
        "\x4f\xba\xc3\x13\xfa\xb1\xa6\xa9"
        "\x69\x09\x48\xe6\xb8\xd5\x55\x12"
        "\xb5\x25\xba\xf6\xd4\x2a\x5e\xf0";
    int i;
    int j;

    for (i = 1; i <= TEST_SHAKE128_MAX_BLOCKS; i++) {
        ExpectIntEQ(wc_InitShake128(&shake128, HEAP_HINT, INVALID_DEVID), 0);

        ExpectIntEQ(wc_Shake128_Absorb(&shake128, (byte*)"Starting point", 15),
            0);

        for (j = 0; j < TEST_SHAKE128_MAX_BLOCKS; j += i) {
            int cnt = TEST_SHAKE128_MAX_BLOCKS - j;
            if (i < cnt)
                cnt = i;
            ExpectIntEQ(wc_Shake128_SqueezeBlocks(&shake128,
                hash + WC_SHA3_128_COUNT * 8 * j, cnt), 0);
        }
        ExpectBufEQ(hash, expOut,
            WC_SHA3_128_COUNT * 8 * TEST_SHAKE128_MAX_BLOCKS);
    }

    wc_Shake128_Free(&shake128);
#endif
    return EXPECT_RESULT();
}

/*******************************************************************************
 * SHAKE-256
 ******************************************************************************/

int test_wc_InitShake256(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    DIGEST_INIT_TEST(wc_Shake, Shake256);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake256_Update(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    DIGEST_ALT_UPDATE_TEST(wc_Shake, Shake256);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake256_Final(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    DIGEST_COUNT_FINAL_TEST(wc_Shake, Shake256, SHA3_256);
#endif
    return EXPECT_RESULT();
}

#define SHAKE256_KAT_CNT    7
int test_wc_Shake256_KATs(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    DIGEST_COUNT_KATS_TEST_VARS(wc_Shake, SHAKE256, SHA3_256);

    DIGEST_KATS_ADD("", 0,
        "\x46\xb9\xdd\x2b\x0b\xa8\x8d\x13"
        "\x23\x3b\x3f\xeb\x74\x3e\xeb\x24"
        "\x3f\xcd\x52\xea\x62\xb8\x1b\x82"
        "\xb5\x0c\x27\x64\x6e\xd5\x76\x2f"
        "\xd7\x5d\xc4\xdd\xd8\xc0\xf2\x00"
        "\xcb\x05\x01\x9d\x67\xb5\x92\xf6"
        "\xfc\x82\x1c\x49\x47\x9a\xb4\x86"
        "\x40\x29\x2e\xac\xb3\xb7\xc4\xbe"
        "\x14\x1e\x96\x61\x6f\xb1\x39\x57"
        "\x69\x2c\xc7\xed\xd0\xb4\x5a\xe3"
        "\xdc\x07\x22\x3c\x8e\x92\x93\x7b"
        "\xef\x84\xbc\x0e\xab\x86\x28\x53"
        "\x34\x9e\xc7\x55\x46\xf5\x8f\xb7"
        "\xc2\x77\x5c\x38\x46\x2c\x50\x10"
        "\xd8\x46\xc1\x85\xc1\x51\x11\xe5"
        "\x95\x52\x2a\x6b\xcd\x16\xcf\x86"
        "\xf3\xd1\x22\x10\x9e\x3b\x1f\xdd");
    DIGEST_KATS_ADD("a", 1,
        "\x86\x7e\x2c\xb0\x4f\x5a\x04\xdc"
        "\xbd\x59\x25\x01\xa5\xe8\xfe\x9c"
        "\xea\xaf\xca\x50\x25\x56\x26\xca"
        "\x73\x6c\x13\x80\x42\x53\x0b\xa4"
        "\x36\xb7\xb1\xec\x0e\x06\xa2\x79"
        "\xbc\x79\x07\x33\xbb\x0a\xee\x6f"
        "\xa8\x02\x68\x3c\x7b\x35\x50\x63"
        "\xc4\x34\xe9\x11\x89\xb0\xc6\x51"
        "\xd0\x92\xb0\x1e\x55\xce\x4d\x61"
        "\x0b\x54\xa5\x46\x6d\x02\xf8\x8f"
        "\xc3\x78\x09\x6f\xb0\xda\xd0\x25"
        "\x48\x57\xfe\x1e\x63\x81\xab\xc0"
        "\x4e\x07\xe3\x3d\x91\x69\x35\x93"
        "\x56\x36\x00\x48\x96\xc5\xb1\x25"
        "\x34\x64\xf1\xcb\x5e\xa7\x3b\x00"
        "\x7b\xc5\x02\x8b\xbb\xea\x13\xeb"
        "\xc2\x86\x68\xdb\xfc\x26\xb1\x24");
    DIGEST_KATS_ADD("abc", 3,
        "\x48\x33\x66\x60\x13\x60\xa8\x77"
        "\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
        "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee"
        "\x4f\x94\xea\x37\xe7\x8b\x57\x39"
        "\xd5\xa1\x5b\xef\x18\x6a\x53\x86"
        "\xc7\x57\x44\xc0\x52\x7e\x1f\xaa"
        "\x9f\x87\x26\xe4\x62\xa1\x2a\x4f"
        "\xeb\x06\xbd\x88\x01\xe7\x51\xe4"
        "\x13\x85\x14\x12\x04\xf3\x29\x97"
        "\x9f\xd3\x04\x7a\x13\xc5\x65\x77"
        "\x24\xad\xa6\x4d\x24\x70\x15\x7b"
        "\x3c\xdc\x28\x86\x20\x94\x4d\x78"
        "\xdb\xcd\xdb\xd9\x12\x99\x3f\x09"
        "\x13\xf1\x64\xfb\x2c\xe9\x51\x31"
        "\xa2\xd0\x9a\x3e\x6d\x51\xcb\xfc"
        "\x62\x27\x20\xd7\xa7\x5c\x63\x34"
        "\xe8\xa2\xd7\xec\x71\xa7\xcc\x29");
    DIGEST_KATS_ADD("message digest", 14,
        "\x71\x8e\x22\x40\x88\x85\x68\x40"
        "\xad\xe4\xdc\x73\x48\x7e\x15\x82"
        "\x6a\x07\xec\xb8\xed\x5e\x2b\xda"
        "\x52\x6c\xc1\xac\xdd\xb9\x9d\x00"
        "\x60\x49\x81\x58\x44\xbe\x0c\x6c"
        "\x29\xb7\x59\xdb\x80\xb7\xda\xa6"
        "\x84\xcb\x46\xd9\x0f\x7e\xef\x10"
        "\x7d\x24\xaa\xfc\xfa\xf0\xda\xca"
        "\xca\x28\x88\xdf\xaa\x73\x76\x94"
        "\xbc\x46\xd5\xc9\x5f\x17\xc5\xcf"
        "\xe7\xb0\xc9\x5c\xfd\x6a\x12\x6d"
        "\xd9\x64\x0c\x8e\x62\xe5\xad\x1c"
        "\x06\xe5\x75\x61\x6a\x2d\xec\x06"
        "\x46\x06\x6e\x80\x37\xe5\x1a\x00"
        "\x54\x78\x3d\x82\x0b\x92\xc1\x14"
        "\x17\x96\xf7\xc3\xe9\x35\x03\x8e"
        "\x67\x13\xbb\xba\x46\x08\x0b\x2e");
    DIGEST_KATS_ADD("abcdefghijklmnopqrstuvwxyz", 26,
        "\xb7\xb7\x8b\x04\xa3\xdd\x30\xa2"
        "\x65\xc8\x88\x6c\x33\xfd\xa9\x47"
        "\x99\x85\x3d\xe5\xd3\xd1\x05\x41"
        "\xfd\x4e\x9f\x46\x13\x70\x1c\x61"
        "\x07\x52\x49\xbe\xd1\x6b\x07\x81"
        "\x10\x8f\xcf\xe0\x86\xdb\xf3\x8a"
        "\x7f\xb8\x30\x08\x07\xce\xa8\x5c"
        "\xc6\x49\x32\x8d\x07\xd4\xff\x2b"
        "\x5e\x89\x08\x56\x3f\xf0\xfd\xcc"
        "\x06\xa8\x09\x2f\xbf\xe7\x72\xf8"
        "\x0e\x49\xf8\x7a\x10\x3b\x2a\xee"
        "\x12\x99\x0c\xcb\x47\x98\xe9\xec"
        "\x03\xaa\x48\x18\xa4\xbf\x5a\xbd"
        "\xa0\x84\xe1\xa5\xfe\x68\x7c\x2c"
        "\xfe\xf4\x40\x68\x46\xfe\x47\xa0"
        "\xd0\x7b\xf4\x50\x55\xa2\x69\x9c"
        "\x37\xd6\xb6\xd9\xcd\x6c\x4f\xf0");
    DIGEST_KATS_ADD("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                    "0123456789", 62,
        "\x31\xf1\x9a\x09\x7c\x72\x3e\x91"
        "\xfa\x59\xb0\x99\x8d\xd8\x52\x3c"
        "\x2a\x9e\x7e\x13\xb4\x02\x5d\x6b"
        "\x48\xfc\xbc\x32\x89\x73\xa1\x08"
        "\x78\xcf\xbe\xb3\x81\x0d\x88\x2f"
        "\xdb\x6a\x06\xe8\x7f\x3e\xa5\x2c"
        "\xf8\x26\xca\x55\x22\x31\x6f\xb6"
        "\x45\xb7\x08\xac\xbe\x43\xb2\xcb"
        "\x32\x52\x09\x24\x32\x42\x70\x60"
        "\xc9\x63\x9e\x21\xa8\x98\xd3\x88"
        "\xa7\xe1\x53\xe4\x2a\x8b\x89\x33"
        "\xf2\xad\x0c\x27\x52\x97\x69\x8e"
        "\x25\x7e\x05\xd2\x62\x75\x39\xb4"
        "\x2c\x10\x1b\x97\x67\xbc\x6d\x90"
        "\x06\x39\x31\x1f\x8e\x4a\x2e\x88"
        "\x26\x7b\xbb\x85\xb3\xfa\x4e\xad"
        "\xf4\x01\xe0\x74\x18\x9f\x6b\xbf");
    DIGEST_KATS_ADD("1234567890123456789012345678901234567890"
                    "1234567890123456789012345678901234567890", 80,
        "\x24\xc5\x08\xad\xef\xdf\x5e\x3f"
        "\x25\x96\xe8\xb5\xa8\x88\xfe\x10"
        "\xeb\x7b\x5b\x22\xe1\xf3\x5d\x85"
        "\x8e\x6e\xff\x30\x25\xc4\xcc\x18"
        "\xa3\xc9\xac\xe5\x1d\xdd\x24\x3d"
        "\x08\xc8\xc7\x0c\xf6\x8e\x91\xd1"
        "\x70\x60\x3d\xc3\xe2\xa3\x1c\x6c"
        "\xa8\x9f\x20\xc4\xa5\x95\xa2\x65"
        "\x4f\xb7\xd5\x35\x29\x42\x7e\x81"
        "\x2d\xea\x48\xe8\xe8\x9a\xbe\x06"
        "\x2b\x88\x90\x2f\x9b\xff\xb5\xee"
        "\xf2\x8a\x65\x80\xfb\x24\x1a\x15"
        "\x20\x1f\x18\xf5\x29\x9d\x03\xc3"
        "\xe7\x17\x3d\x41\x43\x88\x68\x80"
        "\xe4\xfb\x0b\xe1\xf5\x03\xeb\x4a"
        "\x10\x9a\xf6\xf9\xe9\x7f\xa8\xdc"
        "\x2e\xe6\x42\xe3\xc9\x18\x1b\x85");

    DIGEST_COUNT_KATS_TEST(Shake256, SHAKE256, SHA3_256);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake256_other(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    DIGEST_COUNT_OTHER_TEST(wc_Shake, Shake256, SHA3_256,
        "\x97\x52\xa7\xbe\xe4\x06\x06\x10"
        "\xb2\x43\xb5\xca\x1e\x3a\x76\x06"
        "\x68\xac\x62\xfe\xad\xa4\xad\xc9"
        "\x23\xa2\x72\xeb\x90\x54\xeb\xd9"
        "\x06\x7f\x1e\xea\x2d\x80\x92\xb2"
        "\xd1\xe7\xae\x6b\xc0\x1d\x46\x6a"
        "\x3f\x62\x67\x35\x7b\x50\x4b\xe2"
        "\x05\x63\xf7\x97\x10\x4e\x9c\x14"
        "\xff\x21\x64\x40\xf6\xd4\x55\x79"
        "\x2e\x7b\x9b\x5b\xfb\xa2\x15\xf9"
        "\x6d\x6a\x54\xae\x5e\x7d\x6c\x72"
        "\x4a\x4e\x91\xcc\xc2\x37\x1c\x9d"
        "\x14\x95\x27\x38\x64\x6c\x62\x10"
        "\x19\x04\x6f\x19\xde\x61\x5e\xc8"
        "\x6d\xd2\xcc\x5b\xf4\xe0\xf2\x54"
        "\x0f\xe9\x2a\xe7\x0a\x7d\xb0\x55"
        "\x8a\x74\x83\x49\xf0\x2a\x6e\xa9");
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake256_Copy(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    DIGEST_COUNT_COPY_TEST(wc_Shake, Shake256, SHA3_256,
        "\x46\xb9\xdd\x2b\x0b\xa8\x8d\x13"
        "\x23\x3b\x3f\xeb\x74\x3e\xeb\x24"
        "\x3f\xcd\x52\xea\x62\xb8\x1b\x82"
        "\xb5\x0c\x27\x64\x6e\xd5\x76\x2f"
        "\xd7\x5d\xc4\xdd\xd8\xc0\xf2\x00"
        "\xcb\x05\x01\x9d\x67\xb5\x92\xf6"
        "\xfc\x82\x1c\x49\x47\x9a\xb4\x86"
        "\x40\x29\x2e\xac\xb3\xb7\xc4\xbe"
        "\x14\x1e\x96\x61\x6f\xb1\x39\x57"
        "\x69\x2c\xc7\xed\xd0\xb4\x5a\xe3"
        "\xdc\x07\x22\x3c\x8e\x92\x93\x7b"
        "\xef\x84\xbc\x0e\xab\x86\x28\x53"
        "\x34\x9e\xc7\x55\x46\xf5\x8f\xb7"
        "\xc2\x77\x5c\x38\x46\x2c\x50\x10"
        "\xd8\x46\xc1\x85\xc1\x51\x11\xe5"
        "\x95\x52\x2a\x6b\xcd\x16\xcf\x86"
        "\xf3\xd1\x22\x10\x9e\x3b\x1f\xdd",
        "\x48\x33\x66\x60\x13\x60\xa8\x77"
        "\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
        "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee"
        "\x4f\x94\xea\x37\xe7\x8b\x57\x39"
        "\xd5\xa1\x5b\xef\x18\x6a\x53\x86"
        "\xc7\x57\x44\xc0\x52\x7e\x1f\xaa"
        "\x9f\x87\x26\xe4\x62\xa1\x2a\x4f"
        "\xeb\x06\xbd\x88\x01\xe7\x51\xe4"
        "\x13\x85\x14\x12\x04\xf3\x29\x97"
        "\x9f\xd3\x04\x7a\x13\xc5\x65\x77"
        "\x24\xad\xa6\x4d\x24\x70\x15\x7b"
        "\x3c\xdc\x28\x86\x20\x94\x4d\x78"
        "\xdb\xcd\xdb\xd9\x12\x99\x3f\x09"
        "\x13\xf1\x64\xfb\x2c\xe9\x51\x31"
        "\xa2\xd0\x9a\x3e\x6d\x51\xcb\xfc"
        "\x62\x27\x20\xd7\xa7\x5c\x63\x34"
        "\xe8\xa2\xd7\xec\x71\xa7\xcc\x29");
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake256Hash(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    const byte  data[] = { /* Hello World */
        0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
        0x72,0x6c,0x64
    };
    word32      len = sizeof(data);
    byte        hash[WC_SHA3_256_COUNT * 8];
    word32      hashLen = sizeof(hash);
    const char* expHash =
        "\x84\x0d\x1c\xe8\x1a\x43\x27\x84"
        "\x0b\x54\xcb\x1d\x41\x99\x07\xfd"
        "\x1f\x62\x35\x9b\xad\x33\x65\x6e"
        "\x05\x86\x53\xd2\xe4\x17\x2a\x43"
        "\xac\xc9\x58\xdb\xec\x0c\xf0\xd4"
        "\x73\xdb\x45\x8c\xe1\xc0\x07\xaa"
        "\x6e\xb4\x0e\xac\x92\xaa\x0e\x65"
        "\x20\x2e\xdb\x4d\x7f\xee\xd3\x78"
        "\x8a\x77\xed\x6a\x6d\xdc\x5a\xbf"
        "\xbf\xbf\xf7\x2f\x22\xf4\x9e\x66"
        "\x7e\x45\x03\x2c\x1e\xe8\xcf\xb0"
        "\x79\xf8\x08\x9b\x43\xd1\x6a\xe6"
        "\xe5\x8f\x06\x3a\x4d\x93\xef\x36"
        "\x99\xb3\x2b\x9d\x00\xb3\x3c\x37"
        "\x2c\x10\xa4\x8d\x72\xf6\x4d\xa0"
        "\x25\x97\xf4\xfa\x23\xd5\x89\x0a"
        "\x4d\x65\x0a\xcb\x7b\xf8\xd2\x36";

    ExpectIntEQ(wc_Shake256Hash(data, len, hash, hashLen), 0);
    ExpectBufEQ(hash, expHash, hashLen);
#endif
    return EXPECT_RESULT();
}  /* END test_wc_Shake256Hash */

int test_wc_Shake256_Absorb(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake shake256;

    ExpectIntEQ(wc_InitShake256(&shake256, HEAP_HINT, INVALID_DEVID), 0);

#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)
    ExpectIntEQ(wc_Shake256_Absorb(NULL     , NULL    , 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_Absorb(&shake256, NULL    , 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_Absorb(NULL     , NULL    , 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Shake256_Absorb(&shake256, NULL, 0), 0);
#endif
    ExpectIntEQ(wc_Shake256_Absorb(&shake256, (byte*)"a", 1), 0);

    wc_Shake256_Free(&shake256);
#endif
    return EXPECT_RESULT();
}

int test_wc_Shake256_SqueezeBlocks(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake shake256;
    byte hash[WC_SHA3_256_COUNT * 8];

    ExpectIntEQ(wc_InitShake256(&shake256, HEAP_HINT, INVALID_DEVID), 0);

#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)
    ExpectIntEQ(wc_Shake256_SqueezeBlocks(NULL     , NULL, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_SqueezeBlocks(&shake256, NULL, 1),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));
    ExpectIntEQ(wc_Shake256_SqueezeBlocks(NULL     , NULL, 0),
        WC_NO_ERR_TRACE(BAD_FUNC_ARG));

    ExpectIntEQ(wc_Shake256_SqueezeBlocks(&shake256, NULL, 0), 0);
#endif
    ExpectIntEQ(wc_Shake256_SqueezeBlocks(&shake256, hash, 1), 0);

    wc_Shake256_Free(&shake256);
#endif
    return EXPECT_RESULT();
}

#define TEST_SHAKE256_MAX_BLOCKS    3
int test_wc_Shake256_XOF(void)
{
    EXPECT_DECLS;
#ifdef WOLFSSL_SHAKE256
    wc_Shake shake256;
    byte hash[WC_SHA3_256_COUNT * 8 * TEST_SHAKE256_MAX_BLOCKS];
    const char* expOut =
        "\x26\x16\x27\x51\x34\xae\xba\x85"
        "\x2e\x81\x43\x9a\x50\x72\x03\xd8"
        "\x1c\x58\x2b\x87\xb5\x89\x3a\x45"
        "\x66\xfe\x0e\x5a\xde\x60\x8e\xca"
        "\x2e\x27\x87\x25\x08\x0f\x13\x0e"
        "\x4e\x82\xb0\x6a\x4b\xe0\xca\x79"
        "\xcc\x55\xd8\x3f\xb4\x36\x74\x18"
        "\x5d\x2d\xb9\xa7\x95\x25\x6b\x44"
        "\x70\xc5\xa0\xa5\x21\x7e\x88\xed"
        "\x70\x67\x71\x57\x61\xb2\x3c\xb8"
        "\x89\x0f\x43\x28\x8a\xa9\xf1\x29"
        "\x4c\x71\x33\xe7\x96\x4e\x8b\x58"
        "\x7c\x16\x12\xed\xac\x10\xfb\xc8"
        "\xf8\xd2\x1f\xa3\x12\x29\x34\xb2"
        "\xf1\xaa\xcd\x4a\x10\x7a\xd1\x68"
        "\x00\xc1\xb2\xb8\x4b\xb2\xe5\x8a"
        "\xa3\xa0\xda\x73\x15\x3e\xb4\x50"
        "\x70\x3a\x3c\x7f\x8d\xd7\xa8\xfc"
        "\x03\x63\x0f\x80\x15\xd7\x05\x4f"
        "\x48\x42\x52\x12\x4f\xa1\x87\x85"
        "\xb9\xa4\x9b\x04\x17\xdb\x9f\x62"
        "\x9a\xbb\x07\x40\x56\x6c\xb0\xb9"
        "\x20\xf1\x85\x18\x36\x4f\x2e\x71"
        "\x16\x7d\xc0\xed\xb3\x89\x22\x3c"
        "\x93\xbd\xee\x71\x36\x59\x25\x7b"
        "\xae\x3c\x8b\x4b\xa8\xac\x63\xef"
        "\xd5\xfe\x6c\x07\x6b\xb9\x3b\x41"
        "\x8f\x30\x6d\xee\x7b\x1d\xfc\x6c"
        "\xda\x21\x1f\xaa\x63\x72\xc6\xf1"
        "\x51\x27\xce\xdc\x6b\xb2\x84\x7c"
        "\x79\x3b\xa3\xaf\xf0\xb7\x2d\xd8"
        "\x6e\xd9\xc5\x2e\x5e\x48\x42\xbc"
        "\xc3\xe5\x3a\xee\x82\x6c\x90\x21"
        "\xc9\x17\x9e\x17\x2c\x30\x11\x34"
        "\x0a\x53\x33\x93\x47\xca\x7d\x9e"
        "\x4e\xb4\xea\x70\xb7\x58\x39\xc2"
        "\x3c\x29\x6c\x9d\x75\x45\x88\x3d"
        "\x68\x5c\x1c\x6a\x52\x56\x6c\xe5"
        "\x28\x51\xf1\x64\xce\x0b\x45\x66"
        "\x7a\xc4\xb7\x42\x08\x39\x00\x17"
        "\xbe\x55\xd2\xda\x05\x5e\x70\xc3"
        "\xdc\x65\x36\x0b\xa9\x49\x95\xce"
        "\x8a\x04\x04\x4e\xb2\xff\xfa\x31"
        "\x07\x09\x5d\xe4\xa8\x04\x10\xf2"
        "\x84\x3c\x5d\xf4\x99\x5d\x75\x23"
        "\x03\x66\xed\xac\x07\xbb\x89\x61"
        "\xd6\xd0\x5f\x19\xd2\x2f\x1c\xd7"
        "\x73\x4d\x92\x12\x85\x07\x9c\x38"
        "\xd2\x50\x6e\xe5\xe8\x15\x6c\xf6"
        "\xde\x66\x9a\x10\x6f\xa1\xaf\x20"
        "\x99\x1d\xc0\xe6\xdc\xeb\xbc\x74";
    int i;
    int j;

    for (i = 1; i <= TEST_SHAKE256_MAX_BLOCKS; i++) {
        ExpectIntEQ(wc_InitShake256(&shake256, HEAP_HINT, INVALID_DEVID), 0);

        ExpectIntEQ(wc_Shake256_Absorb(&shake256, (byte*)"Starting point", 15),
            0);

        for (j = 0; j < TEST_SHAKE256_MAX_BLOCKS; j += i) {
            int cnt = TEST_SHAKE256_MAX_BLOCKS - j;
            if (i < cnt)
                cnt = i;
            ExpectIntEQ(wc_Shake256_SqueezeBlocks(&shake256,
                hash + WC_SHA3_256_COUNT * 8 * j, cnt), 0);
        }
        ExpectBufEQ(hash, expOut,
            WC_SHA3_256_COUNT * 8 * TEST_SHAKE256_MAX_BLOCKS);
    }

    wc_Shake256_Free(&shake256);
#endif
    return EXPECT_RESULT();
}

